package com.learn.thread;

import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

// 缓存容器，生产者，消费者
public class PCWaitNotifyExample {
    public static void main(String[] args) {
        Buffer buffer = new Buffer(10);
        new Thread(new Producer1(buffer)).start();
        new Thread(new Consumer1(buffer)).start();
    }

}

/**
 * 缓存容器
 */

class Buffer {
    private final Queue<Integer> queue;
    private final int maxCapacity;

    public Buffer(int maxCapacity) {
        this.maxCapacity = maxCapacity;
        this.queue = new LinkedBlockingQueue<>();
    }

    public synchronized void produce(int value) {
        while (queue.size() == maxCapacity) {
            try {
                wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        queue.add(value);
        System.out.println("生产者生产value：" + value + " 当前缓存区间大小为" + queue.size());
        this.notifyAll();
    }

    public synchronized void consumer() {
        while (queue.size() == 0) {
            try {
                wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        Integer value = queue.poll();
        System.out.println("当前消费者消费的value：" + value + " 当前缓存区间大小为" + queue.size());
        notifyAll();
    }
}

/**
 * 生产者
 */
class Producer1 implements Runnable {

    private Buffer buffer;

    public Producer1(Buffer buffer) {
        this.buffer = buffer;
    }

    @Override
    public void run() {
        for (int i = 0; i <= 100; i++) {
            buffer.produce(i);
        }
    }
}

/**
 * 消费者
 */
class Consumer1 implements Runnable {


    private Buffer buffer;

    public Consumer1(Buffer buffer) {
        this.buffer = buffer;
    }

    @Override
    public void run() {
        for (int i = 0; i <= 100; i++) {
            buffer.consumer();
        }
    }
}